﻿using System.Collections.Generic;
using System.Windows;
using System.Windows.Media;
using System.Windows.Shapes;
using ImageProcessing.Common;
using ImageProcessing.Matchers;
using Visualizers.ViewModels;


namespace Visualizers
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private enum ImageType { Primary, Comparision, }

        private readonly Pen _redPen = new Pen(new SolidColorBrush(Colors.Red), 1);
        private readonly Pen _bluePen = new Pen(new SolidColorBrush(Colors.Blue), 1);

        private string _primaryFileName;
        private string _compFileName;

        private int _primaryWidth;
        private int _primaryHeight;

        private int _compWidth;
        private int _compHeight;

        private readonly int? _targetWidth = 640;
        private readonly int? _targetHeight = 480;

        private List<InterestPoint> _compIpts = new List<InterestPoint>();

        private readonly HandlerNearestNeighbour _hnn = new HandlerNearestNeighbour();

        private readonly List<Line> _currentLines = new List<Line>();

        public MainWindow()
        {
            InitializeComponent();
            DataContext = new MainWindowViewModel(Dispatcher);
        }

        //private void OpenImage(object sender, RoutedEventArgs e)
        //{
        //    _primaryFileName = GetFileName();
        //    LoadImage(_primaryFileName, GetDetectorType(), primaryImage, ImageType.Primary, _targetWidth, _targetHeight);
        //}

        //private void OpenImageComp(object sender, RoutedEventArgs e)
        //{
        //    _compFileName = GetFileName();
        //    LoadImage(_compFileName, GetDetectorType(), compImage, ImageType.Comparision, _targetWidth, _targetHeight);
        //}

        //private string GetFileName()
        //{
        //    string filename = string.Empty;

        //    string folderPath = HelperMethods.GetImagePath();

        //    // Configure open file dialog box
        //    var dlg = new Microsoft.Win32.OpenFileDialog
        //                  {
        //                      InitialDirectory = folderPath,
        //                      FileName = "*.raw",
        //                      DefaultExt = ".raw",
        //                  };

        //    // Show open file dialog box
        //    var result = dlg.ShowDialog();

        //    // Process open file dialog box results
        //    if (result == true)
        //    {
        //        // Open document
        //        filename = dlg.FileName;
        //    }

        //    return filename;
        //}

        //private DetectorType GetDetectorType()
        //{
        //    return FastHessian.IsChecked ? DetectorType.FastHessian : DetectorType.FastCorner;
        //}

        //private void LoadImage(string imageFileName, DetectorType detectorType, Image image, ImageType imageType, int? targetWidth = null, int? targetHeight = null)
        //{
        //    var isRawFile = imageFileName.Contains(".raw");

        //    Title = "Loading....";

        //    foreach (var line in _currentLines)
        //    {
        //        drawingSurface.Children.Remove(line);
        //    }

        //    _currentLines.Clear();

        //    if (string.IsNullOrEmpty(imageFileName))
        //    {
        //        Title = "cant find the file.....";
        //        return;
        //    }

        //    var sw = new Stopwatch();
        //    sw.Start();

        //    var pf = isRawFile ? PixelFormats.Gray8 : PixelFormats.Pbgra32;

        //    var writeableBitmap = HelperMethods.LoadImage(imageFileName, pf, targetWidth, targetHeight);

        //    var w = writeableBitmap.PixelWidth;
        //    var h = writeableBitmap.PixelHeight;

        //    if (isRawFile)
        //    {
        //        lock (this)
        //            using (Stream fs = new FileStream(imageFileName.Replace(".raw", ".png"), FileMode.OpenOrCreate))
        //            {
        //                var pbe = new PngBitmapEncoder();
        //                var frame = BitmapFrame.Create(writeableBitmap);
        //                pbe.Frames.Add(frame);
        //                pbe.Save(fs);
        //            }
        //    }

        //    ThreadPool.UnsafeQueueUserWorkItem(o =>
        //                                           {
        //                                               List<InterestPoint> ipts;
        //                                               TagInfo tagInfo = new TagInfo(Guid.NewGuid(), "points");
        //                                               var detector = GetDetector(detectorType, w, h);

        //                                               if (isRawFile)
        //                                               {
        //                                                   var loadedImage = HelperMethods.LoadYImage(imageFileName, w, h);
        //                                                   ipts = detector.GetInterestPoints(ref loadedImage.rawImage);
        //                                                   tagInfo = loadedImage.tagInfo;
        //                                               }
        //                                               else
        //                                               {
        //                                                   var rwImage = HelperMethods.LoadARGBImage(imageFileName, PixelFormats.Pbgra32, w, h);
        //                                                   ipts = detector.GetInterestPoints(ref rwImage);
        //                                               }

        //                                               image.Dispatcher.BeginInvoke(new Action(() => DrawIPoints(image, sw, ipts, h, writeableBitmap, w)));
        //                                               DescribePoints(detector, ipts, tagInfo);

        //                                               if (imageType == ImageType.Primary)
        //                                               {
        //                                                   _primaryWidth = w;
        //                                                   _primaryHeight = h;
        //                                                   //_hnn.Clear();
        //                                                   _hnn.Train(ipts);
        //                                               }
        //                                               else
        //                                               {
        //                                                   _compHeight = h;
        //                                                   _compWidth = w;
        //                                                   _compIpts = ipts;
        //                                               }

        //                                               var foundMatchingPoints = _hnn.Classify(_compIpts).Values.FirstOrDefault();
        //                                               if (foundMatchingPoints == null)
        //                                                   return;

        //                                               drawingSurface.Dispatcher.BeginInvoke(new Action(() => DrawFoundMatchingPoints(foundMatchingPoints)));


        //                                           }, null);
        //}

        //private void DrawFoundMatchingPoints(IList<FeaturesFound> foundMatchingPoints)
        //{
        //    var primaryWidth = primaryImage.ActualWidth / _primaryWidth;
        //    var primaryHeight = primaryImage.ActualHeight / _primaryHeight;

        //    var secondaryWidth = compImage.ActualWidth / _compWidth;
        //    var secondaryHeight = compImage.ActualHeight / _compHeight;

        //    foreach (var foundMatchingPoint in foundMatchingPoints)
        //    {
        //        var pt1 = foundMatchingPoint.KnownInterestPoints;
        //        var pt2 = foundMatchingPoint.ComparisonPoints;

        //        var myLine = new Line
        //                         {
        //                             //Stroke = Brushes.LightSteelBlue,
        //                             Stroke = Brushes.OrangeRed,
        //                             X1 = pt1.X * primaryWidth,
        //                             X2 = pt2.X * secondaryWidth + primaryImage.ActualWidth,
        //                             Y1 = pt1.Y * primaryHeight,
        //                             Y2 = pt2.Y * secondaryHeight,
        //                             StrokeThickness = 2
        //                         };
        //        _currentLines.Add(myLine);
        //        drawingSurface.Children.Add(myLine);

        //    }

        //    Title += string.Format(" points matched {0}", foundMatchingPoints.Count);
        //}

        //private void DescribePoints(IInterestPointDetector detector, List<InterestPoint> interestPoints, TagInfo tagInfo)
        //{
        //    SurfDescriptor.DecribeInterestPoints(interestPoints, false, false, detector.IntegralImage, tagInfo);
        //}

        //private void DrawIPoints(Image image, Stopwatch sw, List<InterestPoint> ipts, int h, WriteableBitmap writeableBitmap, int w)
        //{
        //    var drawingVisual = new DrawingVisual();
        //    var drawingContext = drawingVisual.RenderOpen();

        //    drawingContext.DrawImage(writeableBitmap, new Rect(0, 0, w, h));

        //    ShowInternestPoints(drawingContext, ipts);

        //    drawingContext.Close();

        //    var bmp = new RenderTargetBitmap(w, h, 96, 96, PixelFormats.Pbgra32);

        //    bmp.Render(drawingVisual);
        //    image.Source = bmp;
        //    sw.Stop();
        //    Title = string.Format("Found {0} points in {1}", ipts.Count, sw.Elapsed);
        //}

        //private void ShowInternestPoints(DrawingContext drawingContext, IEnumerable<InterestPoint> ipts)
        //{
        //    foreach (var ip in ipts)
        //    {
        //        var s = 2 * Convert.ToInt32(2.5f * ip.Scale);
        //        var r = Convert.ToInt32(s / 2f);

        //        var myPen = (ip.Sign > 0 ? _bluePen : _redPen);
        //        var ellipseGeometry = new EllipseGeometry(new Rect((ip.X - r), (ip.Y - r), s, s));
        //        drawingContext.DrawGeometry(null, myPen, ellipseGeometry);
        //    }
        //}

        //private IInterestPointDetector GetDetector(DetectorType detectorType, int width, int height)
        //{
        //    IInterestPointDetector result = null;

        //    switch (detectorType)
        //    {
        //        case DetectorType.FastCorner:
        //            result = new FastDetector(width, height) { Threshold = 20, Suppress = true };
        //            break;

        //        case DetectorType.FastHessian:

        //            var intImage = new IntegralImage(width, height);
        //            result = new FastHessian(0.0001f, 5, 2, width, height, intImage);
        //            break;
        //    }

        //    return result;
        //}

        //private void ReloadImages(object sender, RoutedEventArgs e)
        //{
        //    _hnn.Clear();

        //    if (!string.IsNullOrEmpty(_primaryFileName))
        //        LoadImage(_primaryFileName, GetDetectorType(), primaryImage, ImageType.Primary, _targetWidth, _targetHeight);

        //    if (!string.IsNullOrEmpty(_compFileName))
        //        LoadImage(_compFileName, GetDetectorType(), compImage, ImageType.Comparision, _targetWidth, _targetHeight);
        //}

        //private void UseFastHessian(object sender, RoutedEventArgs e)
        //{
        //    FastHessian.IsChecked = true;
        //    FastCorner.IsChecked = false;

        //    ReloadImages(null, null);
        //}

        //private void UseFastCorner(object sender, RoutedEventArgs e)
        //{
        //    FastHessian.IsChecked = false;
        //    FastCorner.IsChecked = true;

        //    ReloadImages(null, null);

        //}

        private void DownLoadImages(object sender, RoutedEventArgs e)
        {
            ((MainWindowViewModel) DataContext).DownloadImagesFromServer();
        }
    }
}
